﻿using System.Collections.Generic;
using CfgTable;
using IQIGame.Onigao.Framework;

namespace IQIGame.Onigao.GamePlay
{
    public static class AttributeDataUtils
    {
        static public int GetEquipChangeAttributeByUpStar(ItemEquipmentData equipItem, int attrCid, int upStarLv)
        {
            if (!TryGetEquipAttribute(equipItem, attrCid, out var attrVal))
            {
                return 0;
            }
            int equipLv = equipItem.level;
            var cfgStarUp = TableCenter.equipStar.GetCfg(equipItem.cid, upStarLv);
            int indexAttrType = GetIndexCfgStarAttrTypes(cfgStarUp, attrCid);
            int addValueUp = indexAttrType < cfgStarUp.DeltaAttrValues.Count ? cfgStarUp.DeltaAttrValues[indexAttrType] : 0;
            int attrValUp = cfgStarUp.AttValues[indexAttrType] + (equipLv * addValueUp);
            return attrValUp - attrVal;
        }

        static private bool TryGetEquipAttribute(ItemEquipmentData equipItem, int attrCid, out int attrValue)
        {
            var cfgStar = equipItem.cfgStar;
            int indexAttrType = GetIndexCfgStarAttrTypes(cfgStar, attrCid);
            if (indexAttrType == -1)
            {
                attrValue = 0;
                return false;
            }

            int addValue = indexAttrType < cfgStar.DeltaAttrValues.Count ? cfgStar.DeltaAttrValues[indexAttrType] : 0;
            attrValue = cfgStar.AttValues[indexAttrType] + (equipItem.level * addValue);
            return true;
        }

        static private int GetIndexCfgStarAttrTypes(CfgEquipStar cfgEquipStar, int attrCid)
        {
            int index = -1;
            for (int i = 0, cnt = cfgEquipStar.AttTypes.Count; i < cnt; i++)
            {
                if (cfgEquipStar.AttTypes[i] == attrCid)
                {
                    index = i;
                    break;
                }
            }
            return index;
        }

        static public int GetEquipChangeAttributeByCompare(ItemEquipmentData equipItem, int attrCid, ItemEquipmentData oldEquipItem)
        {
            if (equipItem == null || oldEquipItem == null || equipItem == oldEquipItem)
            {
                return 0;
            }
            if (!TryGetEquipAttribute(equipItem, attrCid, out var currValue))
            {
                return 0;
            }
            if (!TryGetEquipAttribute(oldEquipItem, attrCid, out var oldValue))
            {
                return 0;
            }
            return currValue - oldValue;
        }

        static public IReadOnlyDictionary<int, int> GetEquipAllAttributeDic(ItemEquipmentData equipItem, List<int> ownEquipSkins)
        {
            Dictionary<int, int> result = new(8);
            var cfgStar = equipItem.cfgStar;
            int cnt = cfgStar.AttTypes.Count; // Math.Min(cfgStar.AttTypes.Count, cfgStar.AttValues.Count);
            for (var i = 0; i < cnt; i++)
            {
                int cid = cfgStar.AttTypes[i];
                int addValue = i < cfgStar.DeltaAttrValues.Count ? cfgStar.DeltaAttrValues[i] : 0;
                result.TryGetValue(cid, out var attrValue);
                result[cid] = attrValue + cfgStar.AttValues[i] + addValue * equipItem.level;
            }
            CalcEquipOwnSkinAttributes(equipItem, ownEquipSkins, result);
            return result;
        }

        static private void CalcEquipOwnSkinAttributes(ItemEquipmentData equipItem, List<int> ownEquipSkins, Dictionary<int, int> dic)
        {
            int cntOwnEquipSkins = ownEquipSkins?.Count ?? 0;
            if (cntOwnEquipSkins == 0)
            {
                return;
            }
            int itemCid = equipItem.cid;
            int cntEquipSkin = TableCenter.equipSkin.CountList(itemCid);

            for (int i = 0; i < cntEquipSkin; i++)
            {
                var cfgEquipSkin = TableCenter.equipSkin.GetCfg(itemCid, i);
                if (cfgEquipSkin == null)
                {
                    LogGame.LogError($"装备皮肤不存在! 装备Cid = {itemCid} , SkinIndex = {i}");
                    continue;
                }

                if (!ownEquipSkins.Contains(cfgEquipSkin.Id))
                {
                    continue;
                }
                CalcEquipSkinAttribute(cfgEquipSkin, dic);
            }
        }

        static private void CalcEquipSkinAttribute(CfgEquipSkin cfgEquipSkin, Dictionary<int, int> dic)
        {
            for (int i = 0, cntAttr = cfgEquipSkin.AttTypes.Count; i < cntAttr; i++)
            {
                int cid = cfgEquipSkin.AttTypes[i];
                dic.TryGetValue(cid, out var attrValue);
                dic[cid] = attrValue + cfgEquipSkin.AttValues[i];
            }
        }

        static public int GetEquipLevelAttributeGrowth(ItemEquipmentData equipItem, int attrCid)
        {
            var cfgStar = equipItem.cfgStar;
            int index = GetIndexCfgStarAttrTypes(cfgStar, attrCid);
            int addValue = index < cfgStar.DeltaAttrValues.Count ? cfgStar.DeltaAttrValues[index] : 0;
            return addValue;
        }
    }
}
